﻿<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Photino 3D Sample Game Project</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <div id="container"></div>

    <script src="js/three.js"></script>
    <script type="text/javascript" src="js/myfont.js"></script>
    <script>
        container = document.getElementById('container');
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(700, 500);
        renderer.setClearColor(0x9999BB, 1);
        container.appendChild(renderer.domElement);

        const camera = new THREE.PerspectiveCamera(45, 2, 2.5, 10000);
        camera.position.set(0, 300, 3500 / 2 + 500);

        const scene = new THREE.Scene();
        scene.add(camera);

        var fieldGeometry = new THREE.BoxGeometry(1200, 50, 3000, 1, 1, 1),
            fieldMaterial = new THREE.MeshLambertMaterial({ color: 0x113377 });
        field = new THREE.Mesh(fieldGeometry, fieldMaterial);
        field.position.set(0, -50, 0);

        scene.add(field);
        paddle1 = addPaddle();
        paddle1.position.z = 3000 / 2;
        paddle2 = addPaddle();
        paddle2.position.z = -3000 / 2;

        var ballGeometry = new THREE.SphereGeometry(20, 16, 16),
            ballMaterial = new THREE.MeshLambertMaterial({ color: 0x39FF14 });
        var ball = new THREE.Mesh(ballGeometry, ballMaterial);
        scene.add(ball);

        let loader = new THREE.FontLoader();
        let loadedFont = loader.parse(rawFont);

        //text3d
        var materialFront = new THREE.MeshBasicMaterial({ color: 0xff1111 });
        var materialSide = new THREE.MeshBasicMaterial({ color: 0x115078 });
        var materialArray = [materialFront, materialSide];
        var textGeom = new THREE.TextGeometry("PONGINO",
            {
                size: 8, height: 4, curveSegments: 1,
                font: loadedFont, weight: "bold", style: "normal",
                bevelThickness: 0.1, bevelSize: 0.5, bevelEnabled: true,
                material: 0, extrudeMaterial: 1
            });

        var textMaterial = new THREE.MeshFaceMaterial(materialArray);
        var textMesh = new THREE.Mesh(textGeom, textMaterial);

        textGeom.computeBoundingBox();

        textMesh.position.x = -1000;
        textMesh.position.y = 300;
        textMesh.position.z = 0;

        textMesh.scale.x = 50.1;
        textMesh.scale.y = 50.1;
        textMesh.scale.z = 50.1;

        textMesh.rotation.x = -Math.PI / 50;
        scene.add(textMesh);

        camera.lookAt(ball.position);

        var mainLight = new THREE.HemisphereLight(0xFFFFFF, 0x000000);
        scene.add(mainLight);

        camera.lookAt(ball.position);

        startRender();

        renderer.domElement.addEventListener('mousemove', containerMouseMove);
        renderer.domElement.style.cursor = 'none';

        function addPaddle() {
            var paddleGeometry = new THREE.BoxGeometry(200, 30, 10, 1, 1, 1),
                paddleMaterial = new THREE.MeshLambertMaterial({ color: 0xFF5555 }),
                paddle = new THREE.Mesh(paddleGeometry, paddleMaterial);
            scene.add(paddle);
            return paddle;
        }
        function startBallMovement() {
            var direction = Math.random() > 0.5 ? -1 : 1;
            ball.$velocity = {
                x: 0,
                z: direction * 20
            };
            ball.$stopped = false;
        }

        function processCpuPaddle() {
            var ballPos = ball.position,
                cpuPos = paddle2.position;

            if (cpuPos.x - 100 > ballPos.x) {
                cpuPos.x -= Math.min(cpuPos.x - ballPos.x, 6);
            } else if (cpuPos.x - 100 < ballPos.x) {
                cpuPos.x += Math.min(ballPos.x - cpuPos.x, 6);
            }
        }

        function processBallMovement() {
            if (!ball.$velocity) {
                startBallMovement();
            }

            if (ball.$stopped) {
                return;
            }

            updateBallPosition();

            if (isSideCollision()) {
                ball.$velocity.x *= -1;
            }

            if (isPaddle1Collision()) {
                hitBallBack(paddle1);
            }

            if (isPaddle2Collision()) {
                hitBallBack(paddle2);
            }
            if (isPastPaddle1()) {
                stopBall();
                setTimeout(reset, 2000);
            }

            if (isPastPaddle2()) {
                stopBall();
                setTimeout(reset, 2000);
            }
        }

        function isPastPaddle1() {
            return ball.position.z > paddle1.position.z + 100;
        }

        function isPastPaddle2() {
            return ball.position.z < paddle2.position.z - 100;
        }

        function updateBallPosition() {
            var ballPos = ball.position;

            ballPos.x += ball.$velocity.x;
            ballPos.z += ball.$velocity.z;
        }

        function isSideCollision() {
            var ballX = ball.position.x,
                halfFieldWidth = 1200 / 2;
            return ballX - 20 < -halfFieldWidth || ballX + 20 > halfFieldWidth;
        }

        function hitBallBack(paddle) {
            ball.$velocity.x = (ball.position.x - paddle.position.x) / 5;
            ball.$velocity.z *= -1;
        }

        function isPaddle2Collision() {
            return ball.position.z - 20 <= paddle2.position.z &&
                isBallAlignedWithPaddle(paddle2);
        }

        function isPaddle1Collision() {
            return ball.position.z + 20 >= paddle1.position.z &&
                isBallAlignedWithPaddle(paddle1);
        }

        function stopBall() {
            ball.$stopped = true;
        }
        function isBallAlignedWithPaddle(paddle) {
            var halfPaddleWidth = 200 / 2,
                paddleX = paddle.position.x,
                ballX = ball.position.x;
            return ballX > paddleX - halfPaddleWidth &&
                ballX < paddleX + halfPaddleWidth;
        }

        function startRender() {
            running = true;
            render();
        }

        function stopRender() {
            running = false;
        }

        function render() {
            if (running) {
                requestAnimationFrame(render);
                processBallMovement();
                processCpuPaddle();
                renderer.render(scene, camera);
            }
        }

        function reset() {
            ball.position.set(0, 0, 0);
            ball.$velocity = null;
        }
        function containerMouseMove(e) {
            var mouseX = e.clientX;
            camera.position.x = paddle1.position.x = -((700 - mouseX) / 700 * 1200) + (1200 / 2);
        }
    </script>
</body>
</html>